package com.dmatek.uwb.packet.bean;
/***
 * 矩阵类
 * @author zhangfu
 * @data 2019年6月22日 下午2:56:49
 * @Description
 */
public final class Matrix 
{
	private int row;
	private int col;
	private double[][] M;
	public Matrix()
	{
		row = col = 3;
		M = new double[row][col];
		identity();
	}
	public Matrix(int row,int col)
	{
		this.row = row;
		this.col = col;
		M = new double[row][col];
		identity();
	}
	public Matrix(int row,int col,double ...ds)
	{
		this.row = row;
		this.col = col;
		M = new double[row][col];
		if(ds.length == row * col)
		{
			for(int i = 0;i < row;i ++)
			{
				for(int j = 0;j < col;j ++)
				{
					M[i][j] =  ds[i * col + j];
				}
			}
		}else
		{
			identity();
		}
	}
	public Matrix(double[][] ds)
	{
		col = ds[0].length;
		row = ds.length;
		M = ds;
	}
	/**
	 * 当前矩阵与另一个同型矩阵相加
	 * @param 被相加的同型矩阵
	 * @return 相加得到的矩阵
	 */
	public Matrix Add(Matrix M1)
	{
		if(row != M1.getRow() || col != M1.getCol())
		{
			return null;
		}
		Matrix M2 = new Matrix(row,col);
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < col;j ++)
			{
				M2.M[i][j] = M1.M[i][j] + M[i][j];
			}
		}
		return M2;
	}
	/**
	 * 当前矩阵减去另一个矩阵
	 * @param 被相减的另一个矩阵
	 * @return 相减得到的矩阵
	 */
	public Matrix Sub(Matrix M1)
	{
		if(row != M1.getRow() || col != M1.getCol())
		{
			return null;
		}
		Matrix M2 = new Matrix(row,col);
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < col;j ++)
			{
				M2.M[i][j] = M[i][j] - M1.M[i][j];
			}
		}
		return M2;
	}
	/**
	 * 当前矩阵与矩阵M1进行乘法运算
	 * 		点乘:第一个矩阵的行与第二个矩阵的列相乘的和为当前矩阵元素的值
	 * @param 被相乘的矩阵
	 * @return 返回相乘矩阵
	 */
	public Matrix PMulti(Matrix M1)
	{
		if(col != M1.getRow())
		{
			return null;
		}
		Matrix M2 = new Matrix(row,M1.getCol());
		double res = 0;
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < M1.getCol();j ++)
			{
				res = 0;
				for(int k = 0;k < col;k ++)
				{
					res += M[i][k] * M1.M[k][j];
				}
				M2.M[i][j] = res;
			}
		}
		return M2;
	}
	/***
	 * 当前矩阵与常量相乘
	 * @param 常量k
	 * @return 与常量相乘得到的矩阵
	 */
	public Matrix CrossMulti(double k)
	{
		Matrix M1 = new Matrix();
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < col;j ++)
			{
				M1.M[i][j] = k * M[i][j];
			}
		}
		return M1;
	}
	/**
	 * 转置矩阵
	 * @return 进过转置后得到的矩阵
	 */
	public Matrix Transpose()
	{
		Matrix M1 = new Matrix(col,row);
		for(int i = 0;i < row;i++)
		{
			for(int j = 0;j < col;j ++)
			{
				M1.M[j][i] = M[i][j];
			}
		}
		return M1;
	}
	/**
	 * 逆矩阵
	 * @return 进行逆运算时得到的矩阵
	 * @throws Exception 通过ToString方法可以输出异常信息
	 */
	public Matrix Inverse() throws Exception
	{
		if(row != col)
		{
			throw new Exception("The inverse matrix doesn't exist!");
		}
		Matrix M2 = Adjoint();
		double val = ValueOf();
		if(val == 0)
			throw new Exception("The inverse matrix doesn't exist!");
		Matrix M1 = new Matrix(row,col);
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < col;j ++)
			{
				
				M1.M[i][j] = M2.M[i][j]/val;
			}
		}
		return M1;
	}
	/***
	 * 伴随矩阵
	 * @return 返回得到的伴随矩阵
	 * @throws Exception 通过ToString可以输出异常讯息
	 */
	public Matrix Adjoint() throws Exception
	{
		if(row != col)
		{
			throw new Exception("The adjoint matrix does not exist!");
		}
		Matrix M1 = new Matrix(row,col);
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < col;j ++)
			{
				Matrix M2 = new Matrix(row - 1,col - 1);
				for(int k = 0;k  < row - 1;k ++)
				{
					for(int m = 0;m < col - 1;m ++)
					{
						M2.M[k][m] = M[k < i?k:k + 1][m < j?m:m + 1];
					}
				}
				M1.M[i][j] = ((i+j)%2 == 0 ? 1:-1) * M2.ValueOf();
			}
		}
		return M1;
	}
	/***
	 * 行列式的值
	 * 原理: 降阶法
	 * 		行列式的值等于任意一行或任意一列的值与其代数余子式的乘积
	 * @return 得到矩阵的值
	 * @throws Exception 通过toString得到异常信息
	 */
	public double ValueOf() throws Exception
	{
		if(row != col)
		{//抛出异常
			throw new Exception("The value of the determinant does not exist!");
		}
		if(row == 1)
		{
			return M[0][0];
		}else if(row == 2)
		{
			return M[0][0] * M[1][1] - M[0][1] * M[1][0];
		}
		Matrix CofactorMatrix = null;//声明代数余子式矩阵
		double res = 0d;
		for(int i = 0;i < row;i ++)
		{
			CofactorMatrix = new Matrix(row - 1, col - 1);
			for(int j = 0;j < row - 1;j ++)
			{
				for(int k = 0;k < row - 1;k++)
				{
					//都是从第二行开始的，所以从j+1为基准
					CofactorMatrix.M[j][k] = M[j + 1][k >= i ? k + 1 : k];
				}
			}
			res += (i%2 == 0?1:-1) * M[0][i] * CofactorMatrix.ValueOf();
		}
		return res;
	}
	/**
	 * 重置为单位矩阵
	 */
	private void identity()
	{
		for(int i = 0;i < row;i++)
		{
			for(int j = 0;j < col;j++)
			{
				if(i == j)M[i][j] = 1;
				else M[i][j] = 0;
			}
		}
	}
	/**
	 * 重写矩阵的toString方法
	 */
	public String toString()
	{
		StringBuilder strbuilder = new StringBuilder();
		strbuilder.append("Matrix Show:\r\n");
		for(int i = 0;i < row;i ++)
		{
			for(int j = 0;j < col;j ++)
			{
				strbuilder.append(M[i][j]);
				strbuilder.append(" ");
			}
			strbuilder.append("\r\n");
		}
		return strbuilder.toString();
	}
	public int getRow() {
		return row;
	}
	public void setRow(int row) {
		this.row = row;
	}
	public int getCol() {
		return col;
	}
	public void setCol(int col) {
		this.col = col;
	}
	public double[][] getM() {
		return M;
	}
	public void setM(double[][] m) {
		M = m;
	}
}
